package burubaka.controller.top;

import java.util.ArrayList;
import java.util.List;

import org.slim3.controller.Navigation;
import org.slim3.util.BeanUtil;

import burubaka.BurubakaConstants;
import burubaka.bean.HandicappingBean;
import burubaka.bean.RankingBean;
import burubaka.common.controller.Controller;
import burubaka.model.BbBbs;
import burubaka.model.Handicapping;
import burubaka.model.PreRaceInfo;
import burubaka.model.RaceInfo;
import burubaka.model.ResultHorse;
import burubaka.model.SystemInfo;
import burubaka.model.Tipster;
import burubaka.model.TotalResult;
import burubaka.service.BbBbsService;
import burubaka.service.HandicappingService;
import burubaka.service.PreRaceInfoService;
import burubaka.service.RaceInfoService;
import burubaka.service.ResultHorseService;
import burubaka.service.SystemInfoService;
import burubaka.service.TipsterService;
import burubaka.service.TotalResultService;

import com.google.appengine.api.datastore.Key;

public class IndexController extends Controller {

	private RaceInfoService raceInfoService = new RaceInfoService();
	private PreRaceInfoService preRaceInfoService = new PreRaceInfoService();
	private SystemInfoService systemInfoService = new SystemInfoService();
	private HandicappingService handicappingService = new HandicappingService();
	private TipsterService tipsterService = new TipsterService();
	private TotalResultService totalResultService = new TotalResultService();
	private ResultHorseService resultHorseService = new ResultHorseService();
	private BbBbsService bbBbsService = new BbBbsService();

	@Override
	public Navigation init() throws Exception {

		SystemInfo systemInfo = systemInfoService.getSystemInfo();
		requestScope("systemInfo", systemInfo);

		// プレレース情報取得
		List<PreRaceInfo> preRaceInfoList = preRaceInfoService.find(4);
		requestScope("preRaceInfoList", preRaceInfoList);

		// レース情報取得
		RaceInfo raceInfo = raceInfoService.getCurrentRaceInfo();
		if (raceInfo == null) {
			return forward("index.jsp");
		}
		requestScope("raceInfo", raceInfo);
		requestScope("resultHorseList", getResultHorseList(raceInfo));

		// 予想取得
		List<Handicapping> handicappingList = handicappingService.getHandicappingList(raceInfo.getRaceDate());
		List<HandicappingBean> ret = getHandicappingBeanList(handicappingList);
		requestScope("handicappingList", ret);

		// 前回予想取得
		RaceInfo lastRaceInfo = raceInfoService.getLastRaceInfo();
		if (lastRaceInfo != null) {
			requestScope("lastRaceInfo", lastRaceInfo);
			requestScope("lastRaceRankingList", getLastRaceRanking(lastRaceInfo));
			requestScope("lastResultHorseList", getResultHorseList(lastRaceInfo));
		}

		// ランキング取得
		requestScope("withdrawalRankingList", getWithdrawalRanking());
		requestScope("withdrawalRateRankingList", getWithdrawalRateRanking());
		requestScope("hitRankingList", getHitRanking());

		// BbBBS取得
		List<BbBbs> bbBbsList = bbBbsService.findAll(BurubakaConstants.BBS_MAX_LINE);
		requestScope("bbBbsList", bbBbsList);

		return forward("index.jsp");
	}

	/**
	 * 結果取得
	 * 
	 * @param raceInfo
	 * @return
	 */
	private List<ResultHorse> getResultHorseList(RaceInfo raceInfo) {
		return resultHorseService.findByResultHorseKey(raceInfo.getKey(), 3);
	}

	/**
	 * 予想一覧を取得する
	 * 
	 * @param raceInfo
	 * @return 予想一覧
	 */
	private List<HandicappingBean> getHandicappingBeanList(List<Handicapping> handicappingList) {
		List<HandicappingBean> ret = new ArrayList<HandicappingBean>();
		for (Handicapping handicapping : handicappingList) {
			HandicappingBean bean = new HandicappingBean();

			Key key = handicapping.getKey().getParent();
			Tipster tipster = tipsterService.findByKey(key);

			BeanUtil.copy(handicapping, bean);
			bean.setNickName(tipster.getNickname());

			if (bean.getWithdrawal() > 0) {
				bean.setHitFlag(BurubakaConstants.FLAG_ON);
			}

			ret.add(bean);
		}
		return ret;
	}

	/**
	 * 前回レースランキングを取得する
	 * 
	 * @return Navigation
	 * @throws List
	 *             <HandicappingBean>
	 */
	private List<HandicappingBean> getLastRaceRanking(RaceInfo raceInfo) throws Exception {
		if (raceInfo == null) {
			return null;
		}
		List<Handicapping> handicappingList = handicappingService.getHandicappingListOrderByWithdrawal(raceInfo
				.getRaceDate());
		List<HandicappingBean> ret = getHandicappingBeanList(handicappingList);

		HandicappingBean oldBean = new HandicappingBean();
		int i = 1;
		for (HandicappingBean bean : ret) {
			bean.setOrder(String.valueOf(i));
			if (bean.getWithdrawal() == oldBean.getWithdrawal()) {
				bean.setOrder(oldBean.getOrder());
			}
			oldBean = bean;
			i++;
		}
		return ret;
	}

	/**
	 * 払戻ランキングを取得する
	 * 
	 * @return Navigation
	 * @throws List
	 *             <RankingBean>
	 */
	private List<RankingBean> getWithdrawalRanking() throws Exception {
		List<TotalResult> totalList = totalResultService.getRankingForWithdrawal(BurubakaConstants.CURRENT_YEAR, 5);
		return getRankingList(totalList, BurubakaConstants.RANKING_WITHDRAWAL);
	}

	/**
	 * 回収率ランキングを取得する
	 * 
	 * @return Navigation
	 * @throws List
	 *             <RankingBean>
	 */
	private List<RankingBean> getWithdrawalRateRanking() throws Exception {
		List<TotalResult> totalList = totalResultService.getRankingForWithdrawalRate(BurubakaConstants.CURRENT_YEAR, 5);
		return getRankingList(totalList, BurubakaConstants.RANKING_WITHDRAWAL_RATE);
	}

	/**
	 * 的中ランキングを取得する
	 * 
	 * @return Navigation
	 * @throws List
	 *             <RankingBean>
	 */
	private List<RankingBean> getHitRanking() throws Exception {
		List<TotalResult> totalList = totalResultService.getRankingForHit(BurubakaConstants.CURRENT_YEAR, 5);
		return getRankingList(totalList, BurubakaConstants.RANKING_HIT);
	}

	/**
	 * ランキングBean取得
	 * 
	 * @param totalList
	 * @return
	 */
	private List<RankingBean> getRankingList(List<TotalResult> totalList, int rankKbn) {
		List<RankingBean> rankingList = new ArrayList<RankingBean>();
		for (TotalResult totalResult : totalList) {
			RankingBean bean = new RankingBean();
			BeanUtil.copy(totalResult, bean);
			Tipster tipster = tipsterService.findByKey(totalResult.getKey().getParent());
			bean.setNickName(tipster.getNickname());

			if (rankKbn == BurubakaConstants.RANKING_WITHDRAWAL) {
				bean.setOrder(totalResult.getWithdrawalOrder());
			}
			if (rankKbn == BurubakaConstants.RANKING_WITHDRAWAL_RATE) {
				bean.setOrder(totalResult.getWithdrawalRateOrder());
			}
			if (rankKbn == BurubakaConstants.RANKING_HIT) {
				bean.setOrder(totalResult.getHitOrder());
			}
			if (rankKbn == BurubakaConstants.RANKING_HIT_RATE) {
				bean.setOrder(totalResult.getHitRateOrder());
			}
			if (totalResult.getBets() == 0) {
				bean.setOrder("-");
			}
			rankingList.add(bean);

		}
		return rankingList;
	}
}
